home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb / sprite / symm_kgdb_remote.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-27  |  34.5 KB  |  1,403 lines

  1. /* Memory-access and commands for inferior process, for GDB.
  2.    Copyright (C)  1988 Free Software Foundation, Inc.
  3.  
  4. GDB is distributed in the hope that it will be useful, but WITHOUT ANY
  5. WARRANTY.  No author or distributor accepts responsibility to anyone
  6. for the consequences of using it or for whether it serves any
  7. particular purpose or works at all, unless he says so in writing.
  8. Refer to the GDB General Public License for full details.
  9.  
  10. Everyone is granted permission to copy, modify and redistribute GDB,
  11. but only under the conditions described in the GDB General Public
  12. License.  A copy of this license is supposed to have been given to you
  13. along with GDB so you can know your rights and responsibilities.  It
  14. should be in a file named COPYING.  Among other things, the copyright
  15. notice and this notice must be preserved on all copies.
  16.  
  17. In other words, go ahead and share GDB, but don't try to stop
  18. anyone else from sharing it farther.  Help stamp out software hoarding!
  19. */
  20.  
  21.  
  22. #include <stdio.h>
  23. #include <sprite.h>
  24. #include <signal.h>
  25. #include <assert.h>
  26.  
  27. #include "defs.h"
  28. #include "param.h"
  29. #include "frame.h"
  30. #include "inferior.h"
  31. #define HAVE_WAIT_STRUCT
  32. #include "wait.h"
  33. #include "kernel/sun3.md/dbg.h"
  34.  
  35.  
  36. #define ERROR_NO_ATTACHED_HOST \
  37.     if (!hostName) error("No machine attached.");
  38.  
  39. #define MARK_DISCONNECTED  {     \
  40.     initialized = 0;          \
  41.     inferior_pid = 0;        \
  42.     hostName = (char *) 0;     \
  43.     free(dataCache);      \
  44.     free(cacheInfo);      \
  45.     }
  46.  
  47.  
  48. int kiodebug;
  49.     static    int    initialized = 0;
  50.  
  51. int icache;
  52.  
  53. /* Descriptor for I/O to remote machine.  */
  54. int remote_desc;
  55.  
  56. #define    PBUFSIZ    300
  57.  
  58.  
  59. /* Maximum number of bytes to read/write at once.  The value here
  60.    is chosen to fill up a packet (the headers account for the 32).  */
  61. #define MAXBUFBYTES ((PBUFSIZ-32)/2)
  62.  
  63. static void remote_send ();
  64. static void putpkt ();
  65. static void getpkt ();
  66. static void dcache_flush ();
  67.  
  68.  
  69. struct sig_mapping_struct {
  70.     char     *sig_name;    /* Print string for signal. */
  71.     int     dbgSig;     /* Boolean - A signal used by the debugger. */
  72.     int     unixSignal;     /* Unix signal equalient. */
  73. } sig_mapping[] =  {
  74.  
  75. /* 0 */     { "Console Interrupt", 0, SIGINT }, 
  76. /* 1 */     { "System Reset", 0, SIGQUIT },
  77. /* 2 */     { "Bus Error", 0, SIGBUS },
  78. /* 3 */     { "Address Error", 0, SIGSEGV },
  79. /* 4 */     { "Illegal Instruction", 0, SIGILL },
  80. /* 5 */     { "Division by zero", 0, SIGFPE } ,
  81. /* 6 */     { "CHK instruction", 0, SIGBUS } ,
  82. /* 7 */     { "Trapv instruction", 0, SIGBUS } ,
  83. /* 8 */     { "Priviledge Violation", 0, SIGSEGV },
  84. /* 9 */     { "Trace Trap", 1,  SIGTRAP },
  85. /* 10 */    { "Emulator 1010 trap", 0,SIGEMT },
  86. /* 11 */    { "Emulator 1111 trap", 0,SIGEMT },
  87. /* 12 */    { "unknown exception", 0, SIGSEGV },
  88. /* 13 */    { "unknown exception", 0, SIGSEGV },
  89. /* 14 */    { "Stack format error", 0,SIGSEGV },
  90. /* 15 */    { "Uninitialized vector", 0,SIGSEGV },
  91. /* 16 */    { "unknown exception", 0, SIGSEGV },
  92. /* 17 */    { "unknown exception", 0, SIGSEGV },
  93. /* 18 */    { "unknown exception", 0, SIGSEGV },
  94. /* 19 */    { "unknown exception", 0, SIGSEGV },
  95. /* 20 */    { "unknown exception", 0, SIGSEGV },
  96. /* 21 */    { "unknown exception", 0, SIGSEGV },
  97. /* 22 */    { "unknown exception", 0, SIGSEGV },
  98. /* 23 */    { "unknown exception", 0, SIGSEGV },
  99. /* 24 */    { "Spurious interrupt", 0, SIGSEGV }, 
  100. /* 25 */    { "Level 1 interrupt", 0, SIGSEGV },
  101. /* 26 */    { "Level 2 interrupt", 0, SIGSEGV },
  102. /* 27 */    { "Level 3 interrupt", 0, SIGSEGV },
  103. /* 28 */    { "Level 4 interrupt", 0, SIGSEGV },
  104. /* 29 */    { "Level 5 interrupt", 0, SIGSEGV },
  105. /* 30 */    { "Level 6 interrupt", 0, SIGSEGV },
  106. /* 31 */    { "Level 7 interrupt", 0, SIGSEGV },
  107. /* 32 */    { "unknown exception", 0, SIGSEGV },
  108. /* 33 */    { "System call trap", 0, SIGSEGV },
  109. /* 34 */    { "Return from signal trap",0, SIGSEGV },
  110. /* 35 */    { "Bad trap",0,SIGSEGV },
  111. /* 36 */    { "unknown exception", 0, SIGSEGV },
  112. /* 37 */    { "unknown exception", 0, SIGSEGV },
  113. /* 38 */    { "unknown exception", 0, SIGSEGV },
  114. /* 39 */    { "unknown exception", 0, SIGSEGV },
  115. /* 40 */    { "unknown exception", 0, SIGSEGV },
  116. /* 41 */    { "unknown exception", 0, SIGSEGV },
  117. /* 42 */    { "unknown exception", 0, SIGSEGV },
  118. /* 43 */    { "unknown exception", 0, SIGSEGV },
  119. /* 44 */    { "unknown exception", 0, SIGSEGV },
  120. /* 45 */    { "unknown exception", 0, SIGSEGV },
  121. /* 46 */    { "unknown exception", 0, SIGSEGV },
  122. /* 47 */    { "Breakpoint trap", 1,SIGTRAP},
  123. /* 48 */    { "Floating point unordered condition", 0, SIGFPE },
  124. /* 49 */    { "Floating point inexact result", 0, SIGFPE },
  125. /* 50 */    { "Floating point divide by zero", 0, SIGFPE },
  126. /* 51 */    { "Floating point underflow", 0, SIGFPE },
  127. /* 52 */    { "Floating point operand error", 0, SIGFPE },
  128. /* 53 */    { "Floating point overflow", 0, SIGFPE },
  129. /* 54 */    { "Floating point not a number", 0, SIGFPE },
  130. /* 55 */    { "unknown exception", 0, SIGSEGV },
  131. };
  132.  
  133. #define    NUM_SIG_MAPS    (sizeof(sig_mapping)/sizeof(sig_mapping[0]))
  134.  
  135. static int lastPid = -1;
  136. char *hostName;
  137.  
  138. /* Open a connection to a remote debugger.
  139.    NAME is the filename used for communication.  */
  140.  
  141. void
  142. remote_open (name, from_tty)
  143.      char *name;
  144.      int from_tty;
  145. {
  146.   if (name[0] == '/')
  147.       name++;
  148.   hostName = savestring(name,strlen(name));
  149.   if (from_tty)
  150.     printf ("Remote debugging using %s\n", name);
  151.   remote_debugging = 1;
  152. }
  153.  
  154. char *
  155. remote_version()
  156. {
  157.   static char    version[1024];
  158.  
  159.   ERROR_NO_ATTACHED_HOST;
  160.   Kdbx_Trace(DBG_GET_VERSION_STRING, 0, version, 1024);
  161.   return version;
  162. }
  163.  
  164. remote_load() { }
  165.  
  166.  
  167.  
  168. /* Tell the remote machine to resume.  */
  169.  
  170. int
  171. remote_resume (step, signal)
  172.      int step, signal;
  173. {
  174.  
  175.   int cur_pc;
  176.   ERROR_NO_ATTACHED_HOST;
  177.   cur_pc = read_pc();
  178.   if (Kdbx_Trace(step ? DBG_SINGLESTEP : DBG_CONTINUE, &cur_pc, 0, 
  179.             sizeof(int)) < 0) {
  180.         error("error trying to continue process\n");
  181.   }
  182.  
  183. }
  184.  
  185. PrintStopInfo(stopInfoPtr)
  186.     StopInfo *stopInfoPtr;
  187. {
  188.  
  189.     assert(NUM_SIG_MAPS == DBG_UNKNOWN_EXC + 1);
  190.     if (stopInfoPtr->trapCode >= NUM_SIG_MAPS) {
  191.         stopInfoPtr->trapCode = NUM_SIG_MAPS-1;
  192.     }
  193.     if (!sig_mapping[stopInfoPtr->trapCode].dbgSig) { 
  194.     printf("Kernel returns with signal (%d) %s\n",stopInfoPtr->trapCode,
  195.             sig_mapping[stopInfoPtr->trapCode].sig_name);
  196.     }
  197. }
  198. /* Wait until the remote machine stops, then return,
  199.    storing status in STATUS just as `wait' would.  */
  200.  
  201. int
  202. remote_wait (status)
  203.      WAITTYPE *status;
  204. {
  205.     StopInfo    stopInfo;
  206.     int    text_size;
  207.     extern CORE_ADDR text_start, text_end;
  208.   ERROR_NO_ATTACHED_HOST;
  209.  
  210.   Kdbx_Trace(DBG_GET_STOP_INFO, (char *) 0, (char *)&stopInfo,
  211.                sizeof(stopInfo));
  212.  
  213.     status->w_status = 0;
  214.     status->w_stopval = WSTOPPED;
  215.     assert(NUM_SIG_MAPS == DBG_UNKNOWN_EXC + 1);
  216.     if (stopInfo.trapCode >= NUM_SIG_MAPS) {
  217.         stopInfo.trapCode = NUM_SIG_MAPS-1;
  218.     }
  219.  
  220.     status->w_stopsig = sig_mapping[stopInfo.trapCode].unixSignal;
  221.     if (!sig_mapping[stopInfo.trapCode].dbgSig) { 
  222.     printf("Kernel returns with signal (%d) %s\n",stopInfo.trapCode,
  223.             sig_mapping[stopInfo.trapCode].sig_name);
  224.     }
  225.  
  226.     text_size = text_end - text_start;
  227.     text_size &= ~(8*1024-1);
  228.     text_start = stopInfo.codeStart - 8*1024;
  229.     text_end = text_start+text_size;
  230.     return status->w_stopsig;
  231. }
  232.  
  233. /* Read the remote registers into the block REGS.  */
  234.  
  235. void
  236. remote_fetch_registers (regs)
  237.      char *regs;
  238. {
  239.   StopInfo    stopInfo;
  240.   ERROR_NO_ATTACHED_HOST;
  241.   Kdbx_Trace(DBG_GET_STOP_INFO, (char *) 0, (char *)&stopInfo,
  242.                sizeof(stopInfo));
  243.   bcopy(stopInfo.genRegs,regs,16*sizeof(int));
  244.   ((int *) regs)[PC_REGNUM] = stopInfo.pc;
  245.   ((int *) regs)[PS_REGNUM] = stopInfo.statusReg;
  246.  
  247. }
  248.  
  249. /* Store the remote registers from the contents of the block REGS.  */
  250.  
  251. void
  252. remote_store_registers (regs)
  253.      char *regs;
  254. {
  255.     char    old_regs[REGISTER_BYTES];
  256.     int    i;
  257.         remote_fetch_registers (old_regs);
  258.     for (i = 0; i < 16; i++) {
  259.         if ( ((int *)regs)[i] != ((int *) old_regs)[i]) {
  260.         Kdbx_Trace(DBG_WRITE_GPR, &(((int *)regs)[i]),i, sizeof(int));
  261.          }    
  262.     }
  263.         
  264. }
  265.  
  266. int
  267. remote_attach(pid)
  268.     int    pid;
  269. {
  270.     int    status;
  271.     ERROR_NO_ATTACHED_HOST;
  272.     if (pid != lastPid) {
  273.     lastPid = pid;
  274.     Kdbx_Trace(DBG_SET_PID, &pid, 0,sizeof(int));
  275.     }
  276.     start_remote();
  277.     return 1;
  278. }
  279. int
  280. remote_detach(sig)
  281.     int    sig;
  282. {
  283.   int cur_pc;
  284.  
  285.   ERROR_NO_ATTACHED_HOST;
  286.   cur_pc = read_pc();
  287.   if (sig) 
  288.       Kdbx_Trace(DBG_DETACH, &cur_pc, 0, sizeof(int));
  289.    remote_clean_up();
  290.    return 0;
  291. }
  292.  
  293.  
  294.  
  295. /* Read a word from remote address ADDR and return it.
  296.    This goes through the data cache.  */
  297.  
  298. int
  299. remote_fetch_word (addr)
  300.      CORE_ADDR addr;
  301. {
  302.  
  303.   int buffer;
  304.   extern CORE_ADDR text_start, text_end;
  305.  
  306.   ERROR_NO_ATTACHED_HOST;
  307.   if (addr >= text_start && addr < text_end)
  308.     {
  309.      Kdbx_Trace(DBG_INST_READ, addr, &buffer, sizeof(int));
  310.       return buffer;
  311.     }
  312.   Kdbx_Trace(DBG_DATA_READ, addr, &buffer, sizeof(int));
  313.   return buffer;
  314. }
  315.  
  316. /* Write a word WORD into remote address ADDR.
  317.    This goes through the data cache.  */
  318.  
  319. void
  320. remote_store_word (addr, word)
  321.      CORE_ADDR addr;
  322.      int word;
  323. {
  324.   extern CORE_ADDR text_start, text_end;
  325.   ERROR_NO_ATTACHED_HOST;
  326.  if (addr >= text_start && addr < text_end)
  327.     {
  328.      Kdbx_Trace(DBG_INST_WRITE, &word, addr, sizeof(word));
  329.       return ;
  330.     }
  331.   Kdbx_Trace(DBG_DATA_WRITE,  &word, addr, sizeof(word));
  332.   return ;
  333. }
  334.  
  335. /* Write memory data directly to the remote machine.
  336.    This does not inform the data cache; the data cache uses this.
  337.    MEMADDR is the address in the remote memory space.
  338.    MYADDR is the address of the buffer in our space.
  339.    LEN is the number of bytes.  */
  340.  
  341. void
  342. remote_write_bytes (memaddr, myaddr, len)
  343.      CORE_ADDR memaddr;
  344.      char *myaddr;
  345.      int len;
  346. {
  347.   ERROR_NO_ATTACHED_HOST;
  348.   Kdbx_Trace(DBG_DATA_WRITE, myaddr, memaddr, len);
  349. }
  350.  
  351. /* Read memory data directly from the remote machine.
  352.    This does not use the data cache; the data cache uses this.
  353.    MEMADDR is the address in the remote memory space.
  354.    MYADDR is the address of the buffer in our space.
  355.    LEN is the number of bytes.  */
  356.  
  357. void
  358. remote_read_bytes (memaddr, myaddr, len)
  359.      CORE_ADDR memaddr;
  360.      char *myaddr;
  361.      int len;
  362. {
  363.  
  364.   ERROR_NO_ATTACHED_HOST;
  365.    Kdbx_Trace(DBG_DATA_READ, memaddr, myaddr, len);
  366. }
  367.  
  368.  
  369. /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
  370.    at debugger address MYADDR.  Returns errno value.  */
  371. int
  372. remote_read_inferior_memory(memaddr, myaddr, len)
  373.      CORE_ADDR memaddr;
  374.      char *myaddr;
  375.      int len;
  376. {
  377.   int xfersize;
  378.   while (len > 0)
  379.     {
  380.       if (len > MAXBUFBYTES)
  381.     xfersize = MAXBUFBYTES;
  382.       else
  383.     xfersize = len;
  384.  
  385.       remote_read_bytes (memaddr, myaddr, xfersize);
  386.       memaddr += xfersize;
  387.       myaddr  += xfersize;
  388.       len     -= xfersize;
  389.     }
  390.   return 0; /* no error */
  391. }
  392.  
  393. /* Copy LEN bytes of data from debugger memory at MYADDR
  394.    to inferior's memory at MEMADDR.  Returns errno value.  */
  395. int
  396. remote_write_inferior_memory (memaddr, myaddr, len)
  397.      CORE_ADDR memaddr;
  398.      char *myaddr;
  399.      int len;
  400. {
  401.   int xfersize;
  402.   while (len > 0)
  403.     {
  404.       if (len > MAXBUFBYTES)
  405.     xfersize = MAXBUFBYTES;
  406.       else
  407.     xfersize = len;
  408.  
  409.       remote_write_bytes(memaddr, myaddr, xfersize);
  410.  
  411.       memaddr += xfersize;
  412.       myaddr  += xfersize;
  413.       len     -= xfersize;
  414.     }
  415.   return 0; /* no error */
  416. }
  417.  
  418. /* 
  419.  * Call a remote function.
  420.  */
  421. call_remote_function(funaddr,nargs,numBytes,argBuffer)
  422.     CORE_ADDR funaddr;
  423.     int        nargs;
  424.     int        numBytes;
  425.     char    *argBuffer;
  426. {
  427.   int    returnValue;
  428.   ERROR_NO_ATTACHED_HOST;
  429.   Kdbx_Trace(DBG_BEGIN_CALL, (char *)0, (char *)0, 0);  
  430.   returnValue = Kdbx_Trace(DBG_CALL_FUNCTION,argBuffer,funaddr,numBytes);
  431.   Kdbx_Trace(DBG_END_CALL, (char *)0, (char *)0, 0);       
  432.   return returnValue;
  433. }
  434.  
  435. void
  436. remote_reboot (args)
  437.      char *args;
  438. {
  439.  
  440.   ERROR_NO_ATTACHED_HOST;
  441.   if (!args)
  442.     args = "";
  443.  
  444.   Kdbx_Trace(DBG_REBOOT, args, NULL, strlen(args));
  445. }
  446.  
  447.  
  448. #include <sys/types.h>
  449. #include <sys/socket.h>
  450. #include <sys/time.h>
  451. #include <netinet/in.h>
  452. #include <netdb.h>
  453. #include <sgtty.h>
  454.  
  455. /*
  456.  * Direct mapped cache of data and code.   The cache is flushed after every
  457.  * step and continue by incrementing the version number.  Flushing code
  458.  * isn't necessary but since kdbx already has an internal code cache it
  459.  * doesn't hurt and makes life easier.
  460.  */
  461. static    int    cacheBlockSize = -1;
  462. static    int    cacheBlockShift = -1;
  463. static    int    cacheSize = 128 * 1024;
  464. #define    CACHE_BLOCK_MASK     (cacheSize / cacheBlockSize - 1)
  465. #define    CACHE_BLOCK_OFFSET_MASK    (cacheBlockSize - 1)
  466. #define    NUM_CACHE_BLOCKS    (cacheSize >> cacheBlockShift)
  467. #define    CACHE_OFFSET_MASK    (cacheSize - 1)
  468. #define    GET_CACHE_BLOCK(address) (((unsigned int) address) >> cacheBlockShift)
  469. /*
  470.  * The data cache is just an array of characters.
  471.  */
  472. static    char    *dataCache;
  473. /*
  474.  * There is information about kept about each cache block.
  475.  */
  476. typedef    struct {
  477.     int        version;    /* Version number of this cache block. */
  478.     char    *realAddr;    /* Actual address of data stored in the block.*/
  479. } CacheInfo;
  480. static CacheInfo    *cacheInfo;
  481. static int    currentVersion = 1;
  482.  
  483. /*
  484.  * Stuff for the serial port.
  485.  */
  486. static    int    kernChannel = 0;
  487. #ifndef KDBX_SERIAL_PORT
  488. #define KDBX_SERIAL_PORT "/dev/ttya"
  489. #endif
  490. static    char kdbxSerialPort[] = KDBX_SERIAL_PORT;
  491. static    int    rs232Debug = 0;
  492.  
  493.  
  494. /*
  495.  * Message buffers.
  496.  */
  497. static Dbg_Msg    msg;
  498. static int    msgSize;
  499. #define    REPLY_BUFFER_SIZE    16384
  500. static    char    replyBuffer[REPLY_BUFFER_SIZE];
  501. static    char    requestBuffer[DBG_MAX_REQUEST_SIZE];
  502. static    int    msgNum = 0;
  503.  
  504. static void    RecvReply();
  505. static int ReadBytes(), WriteBytes();
  506.  
  507. static    struct sockaddr_in    remote;
  508. static    int            kdbxTimeout = 1;
  509. static    int            netSocket;
  510.  
  511.  
  512. /*
  513.  *----------------------------------------------------------------------
  514.  *
  515.  * CreateSocket --
  516.  *
  517.  *    Creates a UDP socket connected to the Sprite host's kernel 
  518.  *    debugger port.
  519.  *
  520.  * Results:
  521.  *    The stream ID of the socket.
  522.  *
  523.  * Side effects:
  524.  *    None.
  525.  *
  526.  *----------------------------------------------------------------------
  527.  */
  528. static int
  529. CreateSocket(spriteHostName)
  530.     char    *spriteHostName;
  531. {
  532.     int            socketID;
  533.     struct hostent     *hostPtr;
  534.  
  535.     hostPtr = gethostbyname(spriteHostName);
  536.     if (hostPtr == (struct hostent *) NULL) {
  537.     error("CreateSocket: unknown host %s\n", spriteHostName);
  538.     }
  539.     if (hostPtr->h_addrtype != AF_INET) {
  540.     error("CreateSocket: bad address type for host %s\n", 
  541.         spriteHostName);
  542.     }
  543.  
  544.     socketID = socket(AF_INET, SOCK_DGRAM, 0);
  545.     if (socketID < 0) {
  546.     perror_with_name("CreateSocket: socket");
  547.     }
  548.  
  549.     bzero((Address)&remote, sizeof(remote));
  550.     bcopy(hostPtr->h_addr, (Address)&remote.sin_addr, hostPtr->h_length);
  551.     remote.sin_port = htons(DBG_UDP_PORT);
  552.     remote.sin_family = AF_INET;
  553.  
  554.     if (connect(socketID, (struct sockaddr *) &remote, sizeof(remote)) < 0) {
  555.     perror_with_name("CreateSocket: connect");
  556.     }
  557.  
  558.     return(socketID);
  559. }
  560.  
  561.  
  562. /*
  563.  * ----------------------------------------------------------------------------
  564.  *
  565.  *  StartDebugger --
  566.  *
  567.  *     Start off a new conversation with the debugger.
  568.  *
  569.  * Results:
  570.  *     None.
  571.  *
  572.  * Side effects:
  573.  *     Setup rs232 channel or network socket.
  574.  * ----------------------------------------------------------------------------
  575.  */
  576. static void
  577. StartDebugger()
  578. {
  579.     if (rs232Debug) {
  580.     unsigned    char    ch;
  581.     struct         sgttyb     modes;
  582.     extern        int promptAfterLoading;
  583.     char        dummyBuffer[BUFSIZ];
  584.     extern        char    *gets();
  585.     int            i;
  586.  
  587.     kernChannel = open(kdbxSerialPort, 2);
  588.     if (kernChannel < 0) {
  589.         perror_with_name("Could not open kernTty\r\n");
  590.         exit(1);
  591.     }
  592.     
  593.     /*
  594.      * Flush the line.
  595.      */
  596.     i = 0;
  597.     ioctl(kernChannel, TIOCFLUSH, &i);
  598.  
  599.     /*
  600.      * Turn off parity and echoing.
  601.      */
  602.     if (ioctl(kernChannel,TIOCGETP,&modes) < 0) {
  603.         perror("ioctl get modes");
  604.         abort();
  605.     }
  606.     modes.sg_flags |= RAW|ANYP;
  607.     modes.sg_flags &= ~ECHO;
  608.     if (ioctl(kernChannel,TIOCSETP,&modes) < 0) {
  609.         perror("ioctl put modes");
  610.         abort();
  611.     }
  612.  
  613.     /*
  614.      * Send the other half a magic sequence of characters that it is
  615.      * waiting for. 
  616.      */
  617.     ch = 127;
  618.     WriteBytes(&ch, 1, 0);
  619.     ch = 27;
  620.     WriteBytes(&ch, 1, 0);
  621.     ch = 7;
  622.     WriteBytes(&ch, 1, 0);
  623.     sleep(5);
  624.     } else {
  625.         char    *host = hostName;
  626.     hostName = (char *) 0;
  627.     netSocket = CreateSocket(host);
  628.     hostName = host;
  629.     }
  630. }
  631.  
  632.  
  633. /*
  634.  * ----------------------------------------------------------------------------
  635.  *
  636.  *  SendRequest --
  637.  *
  638.  *     Send a request message to the kernel.
  639.  *
  640.  * Results:
  641.  *     None.
  642.  *
  643.  * Side effects:
  644.  *     None.
  645.  * ----------------------------------------------------------------------------
  646.  */
  647. static void
  648. SendRequest(numBytes, newRequest)
  649.     int        numBytes;
  650.     Boolean    newRequest;
  651. {
  652.     if (rs232Debug) {
  653.     /*
  654.      * First send the opcode.
  655.      */
  656.     WriteBytes(&msg.opcode, sizeof(msg.opcode), 1);
  657.     if ((Dbg_Opcode) msg.opcode != DBG_DATA_WRITE && 
  658.         (Dbg_Opcode) msg.opcode != DBG_INST_WRITE) {
  659.         /*
  660.          * If not a write send the rest.
  661.          */
  662.         WriteBytes(&msg.data, numBytes - sizeof(msg.opcode), 1);
  663.     } else {
  664.         /*
  665.          * Send the size and numBytes first and then the data.
  666.          */
  667.         WriteBytes(&msg.data.writeMem, 2 * sizeof(int), 1);
  668.         WriteBytes(msg.data.writeMem.buffer,
  669.                    msg.data.writeMem.numBytes, 1);
  670.     }
  671.     } else {
  672.     Dbg_Opcode    opcode;
  673.  
  674.     msgSize = numBytes;
  675.     if (newRequest) {
  676.         msgNum++;
  677.     }
  678.     *(int *)requestBuffer = msgNum;
  679. #ifdef sparc
  680.     bcopy(&msg, requestBuffer + 4, 2);
  681.     bcopy(((char *) &msg)+4, requestBuffer + 6, numBytes-2);
  682. #else
  683.     bcopy(&msg, requestBuffer + 4, numBytes);
  684. #endif
  685.     if (write(netSocket, requestBuffer, numBytes + 4) < numBytes + 4) {
  686.          MARK_DISCONNECTED;
  687.         perror_with_name("SendRequest: Couldn't write to the kernel socket\n");
  688.         return;
  689.     }
  690.     if (newRequest) {
  691.         opcode = (Dbg_Opcode) msg.opcode;
  692.         if (opcode == DBG_DETACH || opcode == DBG_CONTINUE ||
  693.         opcode == DBG_SINGLESTEP || opcode == DBG_DIVERT_SYSLOG || 
  694.         opcode == DBG_BEGIN_CALL || 
  695.         opcode == DBG_WRITE_GPR || opcode == DBG_SET_PID) {
  696.         int    dummy;
  697.         /*
  698.          * Wait for explicit acknowledgments of these packets.
  699.          */
  700.         RecvReply(opcode, 4, &dummy, NULL, 1);
  701.         }
  702.     }
  703.     }
  704. }
  705.  
  706.  
  707. /*
  708.  * ----------------------------------------------------------------------------
  709.  *
  710.  *  RecvReply --
  711.  *
  712.  *     Receive a reply from the kernel.
  713.  *
  714.  * Results:
  715.  *     None.
  716.  *
  717.  * Side effects:
  718.  *     None.
  719.  * ----------------------------------------------------------------------------
  720.  */
  721. static void
  722. RecvReply(opcode, numBytes, destAddr, readStatusPtr, timeout)
  723.     Dbg_Opcode    opcode;
  724.     int        numBytes;
  725.     char    *destAddr;
  726.     int    *readStatusPtr;
  727.     int    timeout;
  728. {
  729.     int        status;
  730.     int     resendRequest = 0;
  731.  
  732.     if (numBytes + 8 > REPLY_BUFFER_SIZE) {
  733.     fprintf(stderr,"numBytes <%d> > REPLY_BUFFER_SIZE <%d>\n",
  734.             numBytes + 8, REPLY_BUFFER_SIZE);
  735.     abort();
  736.     }
  737.     if (rs232Debug) {
  738.     if (opcode == DBG_DATA_READ || opcode == DBG_INST_READ) {
  739.         ReadBytes(&status, sizeof(status));
  740.         if (status == 0) {
  741.         *readStatusPtr = 0;
  742.         return;
  743.         }
  744.         *readStatusPtr = 1;
  745.         ReadBytes(destAddr, numBytes);
  746.     } else if (opcode == DBG_END_CALL) {
  747.         /*
  748.          * End call returns the length and then the data.  First read
  749.          * then length, then the data, then dump the log.
  750.          */
  751.         ReadBytes(&numBytes, sizeof(numBytes));
  752.         if (numBytes == 0) {
  753.         *readStatusPtr = 0;
  754.         } else {
  755.         ReadBytes(replyBuffer, numBytes);
  756.         write(1, replyBuffer, numBytes);
  757.         *readStatusPtr = 1;
  758.         }
  759.     } else {
  760.         ReadBytes(destAddr, numBytes);
  761.     }
  762.     } else {
  763.     int        readMask;
  764.     struct    timeval    interval;
  765.     int        bytesRead;
  766.  
  767.     interval.tv_sec = kdbxTimeout;
  768.     interval.tv_usec = 0;
  769.     do {
  770.         if (timeout) {
  771.         int    numTimeouts;
  772.  
  773.         numTimeouts = 0;
  774.         /*
  775.          * Loop timing out and sending packets until a new packet
  776.          * has arrived.
  777.          */
  778.         do {
  779.             if (!resendRequest) { 
  780.             readMask = 1 << netSocket;
  781.             status = select(32, &readMask, NULL, NULL, &interval);
  782.             } else {
  783.             status = 0;
  784.             resendRequest = 0;
  785.             }
  786.             if (status == 1) {
  787.             break;
  788.             } else if (status == -1) {
  789.                 MARK_DISCONNECTED;
  790.             perror_with_name("RecvReply: Couldn't select on socket.\n");
  791.             } else if (status == 0) {
  792.             SendRequest(msgSize, 0);
  793.             numTimeouts++;
  794.             if (numTimeouts % 10 == 0) {
  795.                 fprintf(stderr, 
  796.                     "Timing out and resending to host %s\n",
  797.                     hostName);
  798.                 fflush(stderr);
  799.                 QUIT;
  800.             }
  801.             }
  802.         } while (1);
  803.         }
  804.         if (opcode == DBG_DATA_READ || opcode == DBG_INST_READ ||
  805.         opcode == DBG_GET_VERSION_STRING) {
  806.         /*
  807.          * Data and instruction reads return variable size packets.
  808.          * The first two ints are message number and status.  If
  809.          * the status is OK then the data follows.
  810.          */
  811.         immediate_quit++;
  812.         bytesRead = read(netSocket, replyBuffer, numBytes + 8);
  813.         immediate_quit--;
  814.         if (bytesRead < 0) {
  815.             MARK_DISCONNECTED;
  816.             perror_with_name("RecvReply: Error reading socket.");
  817.         }
  818.         /*
  819.          * Check message number before the size because this could
  820.          * be an old packet.
  821.          */
  822.         if (*(int *)replyBuffer != msgNum) {
  823.             printf("RecvReply: Old message number = %d, expecting %d\n",
  824.                 *(int *)replyBuffer, msgNum);
  825.             fflush(stdout);
  826.             resendRequest = 1;
  827.             continue;
  828.         }
  829.         if (bytesRead == 8) {
  830.             /*
  831.              * Only 8 bytes so the read failed and there is no data.
  832.              */
  833.             *readStatusPtr = 0;
  834.             return;
  835.         }
  836.             if (opcode == DBG_GET_VERSION_STRING) {
  837.              strncpy(destAddr, (char *)(replyBuffer + 4),numBytes);
  838.              return;
  839.         }
  840.         if (bytesRead != numBytes + 8) {
  841.             printf("RecvReply: Short read (1): op=%d exp=%d read=%d",
  842.                 opcode, numBytes + 4, bytesRead);
  843.             continue;
  844.         }
  845.         *readStatusPtr = 1;
  846.         bcopy(replyBuffer + 8, destAddr, numBytes);
  847.         return;
  848.         } else if (opcode == DBG_END_CALL) {
  849.         int    length;
  850.         /*
  851.          * End call returns a variable size packet that contains
  852.          * the result of the call. The format of the message is 
  853.          * message number, length, data.
  854.          */
  855.         immediate_quit++;
  856.         bytesRead = read(netSocket, replyBuffer, REPLY_BUFFER_SIZE);
  857.         immediate_quit--;
  858.         if (bytesRead < 0) {
  859.             MARK_DISCONNECTED;
  860.             perror_with_name("RecvReply: Error reading socket.");
  861.         }
  862.         /*
  863.          * Check message number before the size because this could
  864.          * be an old packet.
  865.          */
  866.         if (*(int *)replyBuffer != msgNum) {
  867.             printf("RecvReply: Old message number = %d, expecting %d\n",
  868.                 *(int *)replyBuffer, msgNum);
  869.             fflush(stdout);
  870.             resendRequest = 1;
  871.             continue;
  872.         }
  873.         length = *( int *)(replyBuffer + 4);
  874.         if (bytesRead - 8 != length) {
  875.             fprintf(stderr, "RecyReply: Short read for syslog data\n");
  876.             fflush(stderr);
  877.             length = bytesRead - 8;
  878.         }
  879.         if (length == 0) {
  880.             /*
  881.              * No data.
  882.              */
  883.             *readStatusPtr = 0;
  884.             return;
  885.         }
  886.         /*
  887.          * Dump out the buffer.
  888.          */
  889.         write(1, replyBuffer + 8, length);
  890.         *readStatusPtr = 1;
  891.         return;
  892.         } else {
  893.         /*
  894.          * Normal request so just read in the message which includes
  895.          * the message number.
  896.          */
  897.         immediate_quit++;
  898.         bytesRead = read(netSocket, replyBuffer, numBytes + 4);
  899.         immediate_quit--;
  900.         if (bytesRead < 0) {
  901.             MARK_DISCONNECTED;
  902.             perror_with_name("RecvReply: Error reading socket (2).");
  903.         }
  904.         /*
  905.          * Check message number before size because it could be
  906.          * an old packet.
  907.          */
  908.         if (*(int *)replyBuffer != msgNum) {
  909.             printf("RecvReply: Old message number = %d, expecting %d\n",
  910.                 *(int *)replyBuffer, msgNum);
  911.             fflush(stdout);
  912.             resendRequest = 1;
  913.             continue;
  914.         }
  915.         if (bytesRead != numBytes + 4) {
  916.             printf("RecvReply: Short read (2): op=%d exp=%d read=%d",
  917.                 opcode, numBytes + 4, bytesRead);
  918.         }
  919.         if (*(int *)replyBuffer != msgNum) {
  920.             continue;
  921.         }
  922.         bcopy(replyBuffer + 4, destAddr, numBytes);
  923.         return;
  924.         }
  925.     } while (1);
  926.     }
  927. }
  928.  
  929.  
  930. /*
  931.  * ----------------------------------------------------------------------------
  932.  *
  933.  *  WaitForKernel --
  934.  *
  935.  *      Wait for the kernel to send us a message to indicate that it is waiting
  936.  *    to be debugged.
  937.  *
  938.  * Results:
  939.  *     None.
  940.  *
  941.  * Side effects:
  942.  *     None.
  943.  * ----------------------------------------------------------------------------
  944.  */
  945. static void
  946. WaitForKernel()
  947. {
  948.     if (rs232Debug) {
  949.     unsigned char ch;
  950.  
  951.     if (read(kernChannel, &ch, 1) != 1) {
  952.         fprintf(stderr,"Read from kernChannel (2)");
  953.         abort();
  954.     }
  955.     } else {
  956.     int    dummy;
  957.  
  958.     RecvReply(DBG_CONTINUE, 4, &dummy, NULL, 0);
  959.     }
  960. }
  961.  
  962.  
  963. /*
  964.  * ----------------------------------------------------------------------------
  965.  *
  966.  * BlockInCache --
  967.  *
  968.  *     See if the given block at the given address is in the cache.
  969.  *
  970.  * Results:
  971.  *     1 if found block in cache, 0 if didn't.
  972.  *
  973.  * Side effects:
  974.  *     None.
  975.  */
  976. static int
  977. BlockInCache(blockNum, addr)
  978.     int        blockNum;
  979.     char    *addr;
  980. {
  981.     blockNum = blockNum & CACHE_BLOCK_MASK;
  982.     return((int) (cacheInfo[blockNum].version == currentVersion &&
  983.        (unsigned int) cacheInfo[blockNum].realAddr == 
  984.             ((unsigned int) (addr) & ~CACHE_BLOCK_OFFSET_MASK)));
  985. }
  986.  
  987.  
  988. /*
  989.  * ----------------------------------------------------------------------------
  990.  *
  991.  * FetchBlock --
  992.  *
  993.  *     Fetch the given data block from the cache or the kernel if necessary.
  994.  *
  995.  * Results:
  996.  *     1 if could fetch block into cache, 0 if couldn't.
  997.  *
  998.  * Side effects:
  999.  *     Data cache modified.
  1000.  */
  1001. static int
  1002. FetchBlock(blockNum, srcAddr, opcode)
  1003.     int        blockNum;
  1004.     char    *srcAddr;
  1005.     Dbg_Opcode    opcode;
  1006. {
  1007.     int    successfulRead;
  1008.  
  1009.     blockNum = blockNum & CACHE_BLOCK_MASK;
  1010.     srcAddr = (char *) ((unsigned int) (srcAddr) & ~CACHE_BLOCK_OFFSET_MASK);
  1011.  
  1012.     if (BlockInCache(blockNum, srcAddr)) {
  1013.     return(1);
  1014.     }
  1015.     msg.opcode = (short)opcode;
  1016.     msg.data.readMem.address = (int) srcAddr;
  1017.     msg.data.readMem.numBytes = cacheBlockSize;
  1018.     SendRequest(sizeof(msg.opcode) + sizeof(Dbg_ReadMem), 1);
  1019.     RecvReply(opcode, cacheBlockSize, 
  1020.         &dataCache[(unsigned int) (srcAddr) & CACHE_OFFSET_MASK],
  1021.         &successfulRead, 1);
  1022.     if (successfulRead) {
  1023.     cacheInfo[blockNum].version = currentVersion;
  1024.     cacheInfo[blockNum].realAddr = srcAddr;
  1025.     }
  1026.     return(successfulRead);
  1027. }
  1028.  
  1029.  
  1030. /*
  1031.  * ----------------------------------------------------------------------------
  1032.  *
  1033.  * WriteBytes --
  1034.  *
  1035.  *      Write the bytes over to the kernel across the serial line.  Every third
  1036.  *    character that we write is acknowledged by a character that is sent by
  1037.  *    the other kernel.  This is so we don't get ahead of the other kernel.
  1038.  *
  1039.  * Results:
  1040.  *     None.
  1041.  *
  1042.  * Side effects:
  1043.  *     None.
  1044.  *
  1045.  */
  1046. static int
  1047. WriteBytes(buf, numBytes, ack)
  1048.     char *buf;        /* Pointer to buffer to write */
  1049.     int  numBytes;    /* Number of bytes to write */
  1050.     Boolean    ack;    /* Acknowledge when done and every 3 characters. */
  1051. {
  1052.     unsigned char input;
  1053.     int    i;
  1054.     int    toWrite;
  1055.  
  1056.     if (numBytes == 0) {
  1057.     return(0);
  1058.     }
  1059.     if (!ack) {
  1060.     if (write(kernChannel, buf, numBytes) < numBytes) {
  1061.         MARK_DISCONNECTED;
  1062.         perror_with_name("WriteBytes: Couldn't write to the kernel channel\n");
  1063.         return(-1);
  1064.     }
  1065.     return(0);
  1066.     }
  1067.  
  1068.     do {
  1069.     if (numBytes > 3) {
  1070.         toWrite = 3;
  1071.     } else {
  1072.         toWrite = numBytes;
  1073.     }
  1074.     if (write(kernChannel, buf, toWrite) < toWrite) {
  1075.         MARK_DISCONNECTED;
  1076.         perror_with_name("WriteBytes: Couldn't write to the kernel channel\n");
  1077.         return(-1);
  1078.     }
  1079.     buf += toWrite;
  1080.     numBytes -= toWrite;
  1081.  
  1082.     if (read(kernChannel, &input, 1) < 1) {
  1083.         MARK_DISCONNECTED;
  1084.         perror_with_name("WriteBytes: Couldn't read from the kernel channel\n");
  1085.         return(-1);
  1086.     }
  1087.     } while (numBytes > 0);
  1088.  
  1089.     return(0);
  1090. }
  1091.  
  1092.  
  1093. /*
  1094.  * ----------------------------------------------------------------------------
  1095.  *
  1096.  * ReadBytes --
  1097.  *
  1098.  *     Read the given number of bytes over from the kernel on the serial line. 
  1099.  *
  1100.  * Results:
  1101.  *     None.
  1102.  *
  1103.  * Side effects:
  1104.  *     None.
  1105.  *
  1106.  */
  1107. static int
  1108. ReadBytes(buf, numBytes)
  1109.     char *buf;        /* Buffer to read into */
  1110.     int  numBytes;    /* Number of bytes to read */
  1111. {
  1112.     int readSoFar;    /* The total number of bytes that we have read */
  1113.     int bytesRead;    /* The number of bytes read in the last read */
  1114.     int ackCount;    /* The number of bytes that have been acknowledgment */
  1115.  
  1116.     ackCount = 0;
  1117.     readSoFar = 0;
  1118.     while (readSoFar < numBytes) {
  1119.     bytesRead = read(kernChannel, &buf[readSoFar], numBytes - readSoFar);
  1120.     if (bytesRead < 0) {
  1121.         MARK_DISCONNECTED;
  1122.         perror_with_name("ReadBytes: Couldn't read from the kernel channel\n");
  1123.         return(-1);
  1124.     }
  1125.  
  1126.     readSoFar += bytesRead;
  1127.     if (readSoFar - ackCount == DBG_ACK_SIZE) {
  1128.         if (write(kernChannel, &readSoFar, 1) < 1) {
  1129.         MARK_DISCONNECTED;
  1130.         perror_with_name("ReadBytes: Couldn't write to kernel channel\n");
  1131.         return(-1);
  1132.         }
  1133.         ackCount += DBG_ACK_SIZE;
  1134.     }
  1135.     }
  1136.  
  1137.     return(0);
  1138. }
  1139.  
  1140.  
  1141. /*
  1142.  * ----------------------------------------------------------------------------
  1143.  *
  1144.  * Kdbx_Trace --
  1145.  *
  1146.  *     Write the trace command over to the kernel.  
  1147.  *
  1148.  * Results:
  1149.  *     None.
  1150.  *
  1151.  * Side effects:
  1152.  *     None.
  1153.  *
  1154.  * ----------------------------------------------------------------------------
  1155.  */
  1156. int Kdbx_Trace(opcode, srcAddr, destAddr, numBytes)
  1157.     Dbg_Opcode    opcode;        /* Which command */
  1158.     char    *srcAddr;    /* Where to read data from */
  1159.     char    *destAddr;    /* Where to write data to */
  1160.     int        numBytes;    /* The number of bytes to read or write */
  1161. {
  1162.     int            (*intrHandler)();
  1163.     int            i;
  1164.  
  1165.     if (!initialized) {
  1166.     int    moreData;
  1167.     /*
  1168.      * Setup the cache and initiate a conversation with the other kernel.
  1169.      */
  1170.     if (cacheBlockSize == -1) {
  1171.         if (rs232Debug) {
  1172.         cacheBlockSize = 32;
  1173.         cacheBlockShift = 5;
  1174.         } else {
  1175.         cacheBlockSize = 256;
  1176.         cacheBlockShift = 8;
  1177.         }
  1178.     }
  1179.     dataCache = (char *) malloc(cacheSize);
  1180.     cacheInfo = (CacheInfo *) malloc(NUM_CACHE_BLOCKS * sizeof(CacheInfo));
  1181.     for (i = 0; i < NUM_CACHE_BLOCKS; i++) {
  1182.         cacheInfo[i].version = 0;
  1183.     }
  1184.     StartDebugger();
  1185.     /*
  1186.      * Dump the system log by faking a call command.
  1187.      */
  1188.     printf("Dumping system log ...\n");
  1189.     fflush(stdout);
  1190.     msg.opcode = (short)DBG_BEGIN_CALL;
  1191.     SendRequest(sizeof(msg.opcode), 1);
  1192.     msg.opcode = (short)DBG_END_CALL;
  1193.     do {
  1194.         SendRequest(sizeof(msg.opcode), 1);
  1195.         RecvReply(msg.opcode, 0, NULL, &moreData, 1);
  1196.     } while (moreData);
  1197.     initialized = 1;
  1198.     }
  1199.  
  1200.  
  1201.     if (opcode == DBG_DATA_READ || opcode == DBG_INST_READ) {
  1202.     int            firstBlock;
  1203.     int            lastBlock;
  1204.     unsigned    int    cacheOffset;
  1205.     int            toRead;
  1206.  
  1207.     /*
  1208.      * Read using the cache.
  1209.      */
  1210.     firstBlock = GET_CACHE_BLOCK(srcAddr); 
  1211.     lastBlock = GET_CACHE_BLOCK(srcAddr + numBytes - 1);
  1212.     for (i = firstBlock; i <= lastBlock; i++) {
  1213.         cacheOffset = ((unsigned int) srcAddr) & CACHE_OFFSET_MASK;
  1214.         if (i == lastBlock) {
  1215.         toRead = numBytes;
  1216.         } else if (i == firstBlock) {
  1217.         toRead = cacheBlockSize - 
  1218.                 (cacheOffset & CACHE_BLOCK_OFFSET_MASK);
  1219.         } else {
  1220.         toRead = cacheBlockSize;
  1221.         }
  1222.         if (!FetchBlock(i, srcAddr, opcode)) {
  1223.         printf("ERROR: invalid read address 0x%x\n",srcAddr);
  1224.         }
  1225.         bcopy(&dataCache[cacheOffset], destAddr, toRead);
  1226.         srcAddr += toRead;
  1227.         destAddr += toRead;
  1228.         numBytes -= toRead;
  1229.     }
  1230.     return(0);
  1231.     }
  1232.  
  1233.     if (opcode == DBG_DATA_WRITE || opcode == DBG_INST_WRITE) {
  1234.     int    firstBlock;
  1235.     int    lastBlock;
  1236.     int    cacheOffset;
  1237.     int    toWrite;
  1238.     char    *tSrcAddr;
  1239.     char    *tDestAddr;
  1240.     int    tNumBytes;
  1241.  
  1242.     /*
  1243.      * If the block that is being fetched is in the cache then write the
  1244.      * data there first before sending it over to the kernel.
  1245.      */
  1246.     tSrcAddr = srcAddr;
  1247.     tDestAddr = destAddr;
  1248.     tNumBytes = numBytes;
  1249.  
  1250.     firstBlock = GET_CACHE_BLOCK(destAddr); 
  1251.     lastBlock = GET_CACHE_BLOCK(destAddr + numBytes - 1);
  1252.     for (i = firstBlock; i <= lastBlock; i++) {
  1253.         cacheOffset = ((int) tDestAddr) & CACHE_OFFSET_MASK;
  1254.         if (i == lastBlock) {
  1255.         toWrite = tNumBytes;
  1256.         } else if (i == firstBlock) {
  1257.         toWrite = cacheBlockSize - 
  1258.                 (cacheOffset & CACHE_BLOCK_OFFSET_MASK);
  1259.         } else {
  1260.         toWrite = cacheBlockSize;
  1261.         }
  1262.         if (BlockInCache(i, tDestAddr)) {
  1263.         bcopy(tSrcAddr, &dataCache[cacheOffset], tNumBytes);
  1264.         }
  1265.         tSrcAddr += toWrite;
  1266.         tDestAddr += toWrite;
  1267.         tNumBytes -= toWrite;
  1268.     }
  1269.     }
  1270.  
  1271.     msg.opcode = (short) opcode;
  1272.  
  1273.     /*
  1274.      * Do the rest of the work for the desired operation.
  1275.      */
  1276.  
  1277.     switch (opcode) {
  1278.  
  1279.     /*
  1280.      * For these operations the desired data is read from the other
  1281.      * kernel and stored at destAddr.
  1282.      */
  1283.     case DBG_READ_ALL_GPRS:
  1284.     case DBG_GET_STOP_INFO:
  1285.         SendRequest(sizeof(msg.opcode), 1);
  1286.         RecvReply(opcode, numBytes, destAddr, NULL, 1);
  1287.         break;
  1288.  
  1289.     /*
  1290.      * For this operation the desired data is read from srcAddr
  1291.      * and written to the other kernel.
  1292.      */
  1293.     case DBG_SET_PID:
  1294.         msg.data.pid = *(int *)srcAddr;
  1295.         SendRequest(sizeof(msg.opcode) + sizeof(msg.data.pid), 1);
  1296.         break;
  1297.  
  1298.     /*
  1299.      * When writing a general purpose register first the address to write
  1300.      * that is stored in destAddr must be given to the other kernel.
  1301.      * Then the data itself which is stored at srcAddr can be written over.
  1302.      */
  1303.     case DBG_WRITE_GPR:
  1304.         msg.data.writeGPR.regNum = (int) destAddr;
  1305.         msg.data.writeGPR.regVal = *(int *) srcAddr;
  1306.         SendRequest(sizeof(msg.opcode) + sizeof(Dbg_WriteGPR), 1);
  1307.         break;
  1308.  
  1309.     /*
  1310.      * When writing to the kernels instruction or data space first the
  1311.      * address of where to write to (destAddr) and then the number of
  1312.      * bytes to write (numBytes) must be sent over.  Finally all of
  1313.      * the data is read from srcAddr and written over.
  1314.      */
  1315.  
  1316.     case DBG_INST_WRITE:
  1317.     case DBG_DATA_WRITE: {
  1318.         char    writeStatus;
  1319.  
  1320.         msg.data.writeMem.address = (int) destAddr;
  1321.         msg.data.writeMem.numBytes = numBytes;
  1322.         bcopy(srcAddr, msg.data.writeMem.buffer, numBytes);
  1323.         SendRequest(sizeof(msg.opcode) + 2 * sizeof(int) + numBytes, 1);
  1324.         RecvReply(opcode, 1, &writeStatus, NULL, 1);
  1325.         if (writeStatus == 0) {
  1326.         error("ERROR: invalid write address 0x%x\n",destAddr);
  1327.         } 
  1328.         break;
  1329.     }
  1330.     case DBG_DIVERT_SYSLOG:
  1331.         msg.data.syslogCmd = (Dbg_SyslogCmd)srcAddr;
  1332.         SendRequest(sizeof(msg.opcode) + sizeof(Dbg_SyslogCmd), 1);
  1333.         break;
  1334.     case DBG_BEGIN_CALL:
  1335.         SendRequest(sizeof(msg.opcode), 1);
  1336.         break;
  1337.     case DBG_END_CALL: {
  1338.         Boolean    moreData;
  1339.         do {
  1340.         SendRequest(sizeof(msg.opcode), 1);
  1341.         RecvReply(opcode, 0, NULL, &moreData, 1);
  1342.         } while (moreData);
  1343.         break;
  1344.     }
  1345.  
  1346.     case DBG_DETACH: {
  1347.         msg.opcode = (short) DBG_DIVERT_SYSLOG;
  1348.         msg.data.syslogCmd = DBG_SYSLOG_TO_ORIG;
  1349.         SendRequest(sizeof(msg.opcode) + sizeof(Dbg_SyslogCmd), 1);
  1350.  
  1351.         msg.opcode = (short) DBG_DETACH;
  1352.         msg.data.pc = *(int *) srcAddr;
  1353.         SendRequest(sizeof(msg.opcode) + sizeof(msg.data.pc), 1);
  1354.         break;
  1355.     }
  1356.  
  1357.     case DBG_CONTINUE:
  1358.     case DBG_SINGLESTEP:
  1359.         msg.data.pc = *(int *) srcAddr;
  1360.         SendRequest(sizeof(msg.opcode) + sizeof(msg.data.pc), 1);
  1361.         currentVersion++;
  1362.         WaitForKernel();
  1363.         break;
  1364.  
  1365.     case DBG_CALL_FUNCTION: {
  1366.         int        returnValue;
  1367.  
  1368.         msg.data.callFunc.address = (int) destAddr;
  1369.         msg.data.callFunc.numBytes = numBytes;
  1370.         bcopy(srcAddr, msg.data.callFunc.buffer, numBytes);
  1371.         SendRequest(sizeof(msg.opcode) + 2 * sizeof(int) + numBytes, 1);
  1372.         RecvReply(opcode, sizeof(returnValue), &returnValue, NULL, 1);
  1373.         return (returnValue);
  1374.     }
  1375.     case DBG_REBOOT: {
  1376.         msg.data.reboot.stringLength = numBytes;
  1377.         bcopy(srcAddr, msg.data.reboot.string, numBytes);
  1378.         SendRequest(sizeof(msg.opcode) + sizeof(int) + numBytes, 1);
  1379.         return (0);
  1380.     }
  1381.     case DBG_GET_VERSION_STRING: {
  1382.         SendRequest(sizeof(msg.opcode), 1);
  1383.         RecvReply(opcode,numBytes , destAddr, NULL, 1);
  1384.         return (0);
  1385.     }
  1386.     default:
  1387.         printf("Unknown opcode %d\n", opcode);
  1388.         return(-1);
  1389.     }
  1390.     return(0);
  1391. }
  1392. remote_clean_up()
  1393. {
  1394.     MARK_DISCONNECTED;
  1395. }
  1396. remote_close()
  1397. {
  1398. }
  1399. static __initialize_remote ()
  1400. {
  1401. }
  1402.  
  1403.